package cfengMiddleware.server.service.impl;

import CfengMiddleWare.model.entity.RedDetail;
import CfengMiddleWare.model.entity.RedRecord;
import CfengMiddleWare.model.entity.RedRobRecord;
import CfengMiddleWare.model.mapper.RedDetailMapper;
import CfengMiddleWare.model.mapper.RedRecordMapper;
import CfengMiddleWare.model.mapper.RedRobRecordMapper;
import cfengMiddleware.server.dto.RedPackageDto;
import cfengMiddleware.server.service.RedDetailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 红包明细金额 服务实现类
 * </p>
 * 该业务类只是简单的和数据库进行交互，向数据库中插入数据，异步方式，复杂的业务逻辑在核心类中完成
 *
 * @author cfeng
 * @since 2022-09-12
 */
@Service
@Slf4j
@RequiredArgsConstructor
@EnableAsync  //启用异步方法，这样就可以使用@Async开启异步任务（多线程）
public class RedDetailServiceImpl implements RedDetailService {

    //发红包时的红包全局唯一标识等信息
    private final RedRecordMapper redRecordMapper;
    //发红包时随机数算法生成的具体的红包信息
    private final RedDetailMapper redDetailMapper;
    //抢红包相关的信息
    private final RedRobRecordMapper redRobRecordMapper;


    /**
     * 发红包的记录， 采用多线程方式进行记录，开启一个新的线程异步记录
     * @param redPackageDto  红包金额 + 个数
     * @param redId 生成的红包的唯一标识
     * @param list 红包的二倍均值算法生成的唯一标识
     * @throws Exception
     */
    @Async  //异步方法
    @Transactional(rollbackFor = Exception.class) //开启事务
    @Override
    public void recordRedPacket(RedPackageDto redPackageDto, String redId, List<Integer> list) throws Exception {
        //发红包记录
        RedRecord redRecord = new RedRecord();
        //赋值
        redRecord.setUserId(redPackageDto.getUserId());
        redRecord.setRedPacket(redId); //redPacket就是唯一标识
        redRecord.setTotal(redPackageDto.getTotal()); //TOTAL为总数
        redRecord.setAmount(BigDecimal.valueOf(redPackageDto.getAmount()));
        redRecord.setCreateTime(LocalDateTime.now());
        //将发出的红包异步写入RedRecord表
        redRecordMapper.insert(redRecord);
        //发出的红包的均值后的红包记录
        RedDetail redDetail = null;
        //遍历List表将信息写入Detail表
        for(Integer money : list) {
            redDetail = new RedDetail();
            redDetail.setRecordId(redRecord.getId()); //发出的红包写入数据库后
            redDetail.setAmount(BigDecimal.valueOf(money));
            redDetail.setCreateTime(LocalDateTime.now());
            //将每一个小红包的具体信息写入Detail表
            redDetailMapper.insert(redDetail);
        }
    }

    /**
     * 抢红包，抢到之后需要关联用户ID写入抢红包的记录表
     * @param userId  用户ID
     * @param redId 红包全局唯一标识
     * @param amount 抢到的红包金额
     * @throws Exception
     */
    @Override
    @Async  //也是异步的方式，需要将抢到红包的用户异步记录进入数据库
    public void recordRobedPacket(Integer userId, String redId, BigDecimal amount) throws Exception {
        RedRobRecord redRobRecord = new RedRobRecord();
        //录入数据库
        redRobRecord.setUserId(userId);
        redRobRecord.setRedPacket(redId);
        redRobRecord.setAmount(amount);
        redRobRecord.setRobTime(LocalDateTime.now());
        //插入
        redRobRecordMapper.insert(redRobRecord);
    }
}
